package com.ft.web.global;

import com.ft.web.annotation.DisableApiResponseBody;
import com.ft.web.model.ApiResponse;
import com.google.common.collect.ImmutableList;
import org.springframework.core.MethodParameter;
import org.springframework.http.MediaType;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.http.server.ServerHttpRequest;
import org.springframework.http.server.ServerHttpResponse;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.servlet.mvc.method.annotation.ResponseBodyAdvice;

import java.util.List;

/**
 * @copyright (C), 2015-2019, 梵途科技有限公司
 * @fileName: ApiResponseBodyAdvice
 * @author: 李阳
 * @date: 2019/4/17 19:20
 * @description: API响应包装
 */
@ControllerAdvice
public class ApiResponseBodyAdvice implements ResponseBodyAdvice<Object> {

    private static final List<String> SWAGGER_CLASS = ImmutableList.of(
            "springfox.documentation.swagger.web.ApiResourceController",
            "springfox.documentation.swagger2.web.Swagger2Controller",
            "com.github.xiaoymin.swaggerbootstrapui.web.SwaggerBootstrapUiController");

    @Override
    public boolean supports(MethodParameter methodParameter, Class<? extends HttpMessageConverter<?>> aClass) {
        Class<?> declaringClass = methodParameter.getDeclaringClass();

        // 排除异常响应对象
        if (declaringClass.equals(GlobalExceptionHandlerController.class)) {
            return false;
        }
        // 排除swagger
        if (SWAGGER_CLASS.contains(declaringClass.getName())){
            return false;
        }

        DisableApiResponseBody methodAnnotation = methodParameter.getMethodAnnotation(DisableApiResponseBody.class);
        if (null == methodAnnotation) {
            DisableApiResponseBody annotation = declaringClass.getAnnotation(DisableApiResponseBody.class);
            return null == annotation;
        } else {
            return false;
        }
    }

    @Override
    public Object beforeBodyWrite(Object o, MethodParameter methodParameter, MediaType mediaType, Class<? extends HttpMessageConverter<?>> aClass, ServerHttpRequest serverHttpRequest, ServerHttpResponse serverHttpResponse) {
        ApiResponse<Object> resultWrapper = new ApiResponse<>();
        resultWrapper.setPath(serverHttpRequest.getURI().getPath());
        resultWrapper.setResult(o);
        return resultWrapper;
    }
}
